package com.service.impl;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dao.ArticleActionDAO;
import com.dao.ArticleCommentDAO;
import com.dao.ArticleDAO;
import com.dao.TagDAO;
import com.dao.TimelineDAO;
import com.dao.UserDAO;
import com.model.Article;
import com.model.ArticleAction;
import com.model.ArticleComment;
import com.model.Tag;
import com.model.Timeline;
import com.model.User;
import com.service.ArticleService;
import com.util.Page;

@Service
public class ArticleServiceImpl implements ArticleService {

	@Autowired
	private UserDAO userDAO;

	@Autowired
	private TagDAO tagDAO;

	@Autowired
	private ArticleDAO articleDAO;

	@Autowired
	private ArticleActionDAO articleActionDAO;

	@Autowired
	private TimelineDAO timelineDAO;

	@Autowired
	private ArticleCommentDAO articleCommentDAO;

	@Transactional
	public Page findPageByUserId(int uid, int page, int pageSize) {

		return articleDAO.findPageByUserId(uid, page, pageSize, false);
	}

	@Transactional
	public Page findPageByUserIdPublic(int uid, int page, int pageSize) {

		return articleDAO.findPageByUserId(uid, page, pageSize, true);
	}

	@Transactional
	public List<Article> findCollectPageByUserId(int uid, int page, int pageSize) {

		return articleDAO.findCollectPageByUserId(uid, page, pageSize);
	}

	@Transactional
	public Article addArticle(Article article, List<String> tagNames) {
		int uid = article.getUser().getId();
		article.setCreateAt(new Date());
		userDAO.addArticleNum(uid);
		articleDAO.add(article);
		Timeline t = new Timeline(article.getUser(), "article", article.getId(), new Date());
		t.setIsPublic(article.getIsPublic());
		timelineDAO.addEvent(t);
		for (String tagName : tagNames) {
			this.addArticleTag(article.getId(), tagName);
		}
		return article;
	}

	@SuppressWarnings("rawtypes")
	@Transactional
	public int deleteArticle(int articleId) {
		Article article = articleDAO.findById(articleId);
		int userId = article.getUser().getId();
		userDAO.reduceArticleNum(userId);
		Iterator it = article.getTags().iterator();
		for (; it.hasNext();) {
			Tag tag = (Tag) it.next();
			tag.setArticleNum(tag.getArticleNum() - 1);
			tagDAO.update(tag);
		}
		articleDAO.delete(articleId);
		return articleId;
	}

	@Transactional
	public int addArticleTag(int articleId, String tagName) {
		List<Tag> tagList = tagDAO.findByName(tagName);
		int tagId = 0;
		if (tagList.size() == 0) {
			Tag tag = new Tag();
			tag.setName(tagName);
			tag.setDescription(tagName);
			tag.setArticleNum(1);
			tag.setQuestionNum(0);
			tag.setUserNum(0);
			tag.setIsElite(0);
			tag.setImage("");
			tagDAO.addTag(tag);
			tagId = tag.getId();
			articleDAO.addTag(articleId, tagId);
		}
		else {
			Tag tag = tagList.get(0);
			tagId = tag.getId();
			if (articleDAO.isTagExist(articleId, tagId)) {
				return 0;
			}
			else {
				tag.setArticleNum(tag.getArticleNum() + 1);
				tagDAO.update(tag);
				articleDAO.addTag(articleId, tagId);
			}

		}
		return articleId;
	}

	@Transactional
	public void setPublic(int articleId) {
		articleDAO.makePublic(articleId, true);
	}

	@Transactional
	public void setPrivate(int articleId) {
		articleDAO.makePublic(articleId, false);
	}

	@Transactional
	public String favorArticle(int articleId, int userId) {
		if (articleActionDAO.isExist(articleId, userId, "favor")) {
			return "exist";
		}
		else {
			ArticleAction aa = new ArticleAction();
			User u = new User();
			u.setId(userId);
			Article a = new Article();
			a.setId(articleId);

			aa.setUser(u);
			aa.setArticle(a);
			aa.setActionType("favor");
			aa.setCreateAt(new Date());
			articleActionDAO.add(aa);
			articleDAO.addFavorNum(articleId);
			return "success";
		}

	}

	@Transactional
	public String agreeArticle(int articleId, int userId) {
		if (articleActionDAO.isExist(articleId, userId, "agree")) {
			return "exist";
		}
		else {
			ArticleAction aa = new ArticleAction();
			User u = new User();
			u.setId(userId);
			Article a = new Article();
			a.setId(articleId);

			aa.setUser(u);
			aa.setArticle(a);
			aa.setActionType("agree");
			aa.setCreateAt(new Date());
			articleActionDAO.add(aa);
			articleDAO.addAgreeNum(articleId);
			return "success";
		}

	}

	@Transactional
	public String disagreeArticle(int articleId, int userId) {
		if (articleActionDAO.isExist(articleId, userId, "agree")) {
			return "exist";
		}
		else {
			ArticleAction aa = new ArticleAction();
			User u = new User();
			u.setId(userId);
			Article a = new Article();
			a.setId(articleId);

			aa.setUser(u);
			aa.setArticle(a);
			aa.setActionType("disagree");
			aa.setCreateAt(new Date());
			articleActionDAO.add(aa);
			articleDAO.addDisagreeNum(articleId);
			return "success";
		}

	}

	@Transactional
	public String collectArticle(int articleId, int userId) {
		if (articleActionDAO.isExist(articleId, userId, "collect")) {
			return "exist";
		}
		else {
			ArticleAction aa = new ArticleAction();
			User u = new User();
			u.setId(userId);
			Article a = new Article();
			a.setId(articleId);

			aa.setUser(u);
			aa.setArticle(a);
			aa.setActionType("collect");
			aa.setCreateAt(new Date());
			articleActionDAO.add(aa);
			articleDAO.addCollectNum(articleId);
			return "success";
		}

	}

	@Transactional
	public String cancelCollectArticle(int articleId, int userId) {
		if (!articleActionDAO.isExist(articleId, userId, "collect")) {
			return "noexist";
		}
		else {
			articleActionDAO.cancleCollect(articleId, userId);
			articleDAO.reduceCollectNum(articleId);
			return "success";
		}
	}

	@Transactional
	public Article findArticleById(int id) {
		return articleDAO.findById(id);
	}

	@Transactional
	public Article findArticleByIdWithUser(int id) {
		return articleDAO.findByIdWithUser(id);
	}

	@Transactional
	public List<Tag> findArticleTags(int articleId) {
		// TODO Auto-generated method stub
		return articleDAO.findTagsByArticleId(articleId);
	}

	@Transactional
	public List findCommentsByPage(int articleId, int page, int pageSize) {
		List list = articleCommentDAO.findByPage(articleId, page, pageSize);

		return list;
	}

	@Transactional
	public void doCommentAction(int targetId, String action) {
		// TODO Auto-generated method stub
		if(action.equals("agree")){
			articleCommentDAO.addAgree(targetId);
		}else if(action.equals("disagree")){
			articleCommentDAO.addDisagree(targetId);
		}
	}
	
	@Transactional
	public void addComment(int aid, int uid, String comment) {
		try {
			Article a = new Article();
			a.setId(aid);
			User u = new User();
			u.setId(uid);

			ArticleComment c = new ArticleComment();
			c.setArticle(a);
			c.setUser(u);
			c.setContents(comment);
			c.setCreateAt(new Date());
			c.setAgreeNum(0);
			c.setDisagreeNum(0);
			articleCommentDAO.add(c);
			articleDAO.addCommentNum(aid);
		}
		catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	@Transactional
	public List findNewArticleTopN(int topN) {
		// TODO Auto-generated method stub
		return articleDAO.findNewArticleTopN(topN);
	}
	@Transactional
	public List findHotArticleTopN(int topN) {
		// TODO Auto-generated method stub
		return articleDAO.findHotArticleTopN(topN);
	}

	
}
